#ifndef SOCKET_H
#define SOCKET_H

#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

class Socket
{
private:
    int m_sockfd;
    static const std::string defaultip;
    static const int MAX_LISTEN = 5;
public:
    Socket();
    Socket(int fd);
    ~Socket();
    int fd();
    // 创建套接字
    bool create();
    // 关闭套接字
    void close();

    // 绑定地址信息
    bool bind(const std::string &ip, uint16_t port);
    
    // Tcp server开始监听
    bool listen(int backlog = MAX_LISTEN);
    
    // server获取新连接
    int accept();
    
    // client发起连接
    bool connect(const std::string &ip, uint16_t port);

    // Tcp接受数据
    // 阻塞版本
    ssize_t recv(void *buf, size_t size, int flag = 0);
    
    // 非阻塞版本
    ssize_t nonBlockRecv(void *buf, size_t size);
    
    // Tcp发送数据
    // 阻塞版本
    ssize_t send(const void *buf, size_t size, int flag = 0);
    
    // 非阻塞版本
    ssize_t nonBlockSend(void *buf, size_t size);
    
    // 设置套接字属性
    // 设置套接字选项---开启地址端口重用
    void reuseAddress();
    
    // 设置套接字阻塞属性-- 设置为非阻塞
    void nonBlock();
    
    // 创建一个TCP服务端连接
    bool createTcpServer(uint16_t port, const std::string &ip = defaultip, bool block_flag = false);
    
    // 创建一个客户端连接
    bool createTcpClient(uint16_t port, const std::string &ip);
};

#endif